package com.leilei.entity;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;

import java.nio.charset.StandardCharsets;

/**
 * @author: lei
 * @date: 2025-05-21 11:38
 * @desc: 基于 HuTool 封装的 SM4 加密器，默认使用Base64
 */

public class Sm4Encryptor {

    private final SM4 sm4;

    private final EncryptProperties.EncryptType encryptType;
    private final String encryptPrefix;

    public Sm4Encryptor(EncryptProperties properties) {
        String key = properties.getSm4Key();
        if (StrUtil.isBlank(key) || key.length() != 16) {
            throw new IllegalArgumentException("SM4密钥必须为16位字符串");
        }
        this.sm4 = SmUtil.sm4(key.getBytes(StandardCharsets.UTF_8));
        this.encryptType = properties.getEncryptType() != null ? properties.getEncryptType() : EncryptProperties.EncryptType.SM4BASE64;
        this.encryptPrefix = properties.getEncryptPrefix();
    }

    /**
     * 加密明文
     *
     * @param plainText 明文字符串
     * @return 密文字符串（HEX 或 BASE64）
     */
    public String encrypt(String plainText) {
        if (StrUtil.isBlank(plainText)) {
            return plainText;
        }
        if (plainText.startsWith(encryptPrefix)) {
            return plainText;
        }
        byte[] encrypted = sm4.encrypt(plainText);
        if (EncryptProperties.EncryptType.SM4BASE64.equals(encryptType)) {
            return encryptPrefix + cn.hutool.core.codec.Base64.encode(encrypted);
        } else {
            return encryptPrefix + HexUtil.encodeHexStr(encrypted);
        }
    }

    /**
     * 解密密文
     *
     * @param cipherText HEX 或 BASE64 格式密文
     * @return 解密后的明文
     */
    public String decrypt(String cipherText) {
        if (StrUtil.isBlank(cipherText)) {
            return cipherText;
        }
        if (cipherText.startsWith(encryptPrefix)) {
            cipherText = cipherText.substring(encryptPrefix.length());
        } else {
            return cipherText;
        }
        byte[] cipherBytes;
        if (EncryptProperties.EncryptType.SM4BASE64.equals(encryptType)) {
            cipherBytes = cn.hutool.core.codec.Base64.decode(cipherText);
        } else {
            cipherBytes = HexUtil.decodeHex(cipherText);
        }

        return sm4.decryptStr(cipherBytes, StandardCharsets.UTF_8);
    }
}
